

using System;
using System.Linq;
using System.Linq.Dynamic.Core;
using Abp.Linq.Extensions;
using System.Collections.Generic;
using System.Threading.Tasks;
using Abp.Domain.Repositories;
using Dyan.PlatformSystem.Customers.Exporting;
using Dyan.PlatformSystem.Customers.Dtos;
using Dyan.PlatformSystem.Dto;
using Abp.Application.Services.Dto;
using Dyan.PlatformSystem.Authorization;
using Abp.Extensions;
using Abp.Authorization;
using Microsoft.EntityFrameworkCore;

namespace Dyan.PlatformSystem.Customers
{
	[AbpAuthorize(AppPermissions.Pages_CustomerAccounts)]
    public class CustomerAccountsAppService : PlatformSystemAppServiceBase, ICustomerAccountsAppService
    {
		 private readonly IRepository<CustomerAccount, Guid> _customerAccountRepository;
		 private readonly ICustomerAccountsExcelExporter _customerAccountsExcelExporter;
		 

		  public CustomerAccountsAppService(IRepository<CustomerAccount, Guid> customerAccountRepository, ICustomerAccountsExcelExporter customerAccountsExcelExporter ) 
		  {
			_customerAccountRepository = customerAccountRepository;
			_customerAccountsExcelExporter = customerAccountsExcelExporter;
			
		  }

		 public async Task<PagedResultDto<GetCustomerAccountForViewDto>> GetAll(GetAllCustomerAccountsInput input)
         {
			
			var filteredCustomerAccounts = _customerAccountRepository.GetAll()
						.WhereIf(!string.IsNullOrWhiteSpace(input.Filter), e => false  || e.Name.Contains(input.Filter) || e.Email.Contains(input.Filter) || e.PhoneNum.Contains(input.Filter) || e.PassWord.Contains(input.Filter))
						.WhereIf(!string.IsNullOrWhiteSpace(input.NameFilter),  e => e.Name.ToLower() == input.NameFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.EmailFilter),  e => e.Email.ToLower() == input.EmailFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.PhoneNumFilter),  e => e.PhoneNum.ToLower() == input.PhoneNumFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.PassWordFilter),  e => e.PassWord.ToLower() == input.PassWordFilter.ToLower().Trim());

			var pagedAndFilteredCustomerAccounts = filteredCustomerAccounts
                .OrderBy(input.Sorting ?? "id asc")
                .PageBy(input);

			var customerAccounts = from o in pagedAndFilteredCustomerAccounts
                         select new GetCustomerAccountForViewDto() {
							CustomerAccount = new CustomerAccountDto
							{
                                Name = o.Name,
                                Email = o.Email,
                                PhoneNum = o.PhoneNum,
                                PassWord = o.PassWord,
                                Id = o.Id
							}
						};

            var totalCount = await filteredCustomerAccounts.CountAsync();

            return new PagedResultDto<GetCustomerAccountForViewDto>(
                totalCount,
                await customerAccounts.ToListAsync()
            );
         }
		 
		 public async Task<GetCustomerAccountForViewDto> GetCustomerAccountForView(Guid id)
         {
            var customerAccount = await _customerAccountRepository.GetAsync(id);

            var output = new GetCustomerAccountForViewDto { CustomerAccount = ObjectMapper.Map<CustomerAccountDto>(customerAccount) };
			
            return output;
         }
		 
		 [AbpAuthorize(AppPermissions.Pages_CustomerAccounts_Edit)]
		 public async Task<GetCustomerAccountForEditOutput> GetCustomerAccountForEdit(EntityDto<Guid> input)
         {
            var customerAccount = await _customerAccountRepository.FirstOrDefaultAsync(input.Id);
           
		    var output = new GetCustomerAccountForEditOutput {CustomerAccount = ObjectMapper.Map<CreateOrEditCustomerAccountDto>(customerAccount)};
			
            return output;
         }

		 public async Task CreateOrEdit(CreateOrEditCustomerAccountDto input)
         {
            if(input.Id == null){
				await Create(input);
			}
			else{
				await Update(input);
			}
         }

		 [AbpAuthorize(AppPermissions.Pages_CustomerAccounts_Create)]
		 protected virtual async Task Create(CreateOrEditCustomerAccountDto input)
         {
            var customerAccount = ObjectMapper.Map<CustomerAccount>(input);

			
			if (AbpSession.TenantId != null)
			{
				customerAccount.TenantId = (int) AbpSession.TenantId;
			}
		

            await _customerAccountRepository.InsertAsync(customerAccount);
         }

		 [AbpAuthorize(AppPermissions.Pages_CustomerAccounts_Edit)]
		 protected virtual async Task Update(CreateOrEditCustomerAccountDto input)
         {
            var customerAccount = await _customerAccountRepository.FirstOrDefaultAsync((Guid)input.Id);
             ObjectMapper.Map(input, customerAccount);
         }

		 [AbpAuthorize(AppPermissions.Pages_CustomerAccounts_Delete)]
         public async Task Delete(EntityDto<Guid> input)
         {
            await _customerAccountRepository.DeleteAsync(input.Id);
         } 

		public async Task<FileDto> GetCustomerAccountsToExcel(GetAllCustomerAccountsForExcelInput input)
         {
			
			var filteredCustomerAccounts = _customerAccountRepository.GetAll()
						.WhereIf(!string.IsNullOrWhiteSpace(input.Filter), e => false  || e.Name.Contains(input.Filter) || e.Email.Contains(input.Filter) || e.PhoneNum.Contains(input.Filter) || e.PassWord.Contains(input.Filter))
						.WhereIf(!string.IsNullOrWhiteSpace(input.NameFilter),  e => e.Name.ToLower() == input.NameFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.EmailFilter),  e => e.Email.ToLower() == input.EmailFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.PhoneNumFilter),  e => e.PhoneNum.ToLower() == input.PhoneNumFilter.ToLower().Trim())
						.WhereIf(!string.IsNullOrWhiteSpace(input.PassWordFilter),  e => e.PassWord.ToLower() == input.PassWordFilter.ToLower().Trim());

			var query = (from o in filteredCustomerAccounts
                         select new GetCustomerAccountForViewDto() { 
							CustomerAccount = new CustomerAccountDto
							{
                                Name = o.Name,
                                Email = o.Email,
                                PhoneNum = o.PhoneNum,
                                PassWord = o.PassWord,
                                Id = o.Id
							}
						 });


            var customerAccountListDtos = await query.ToListAsync();

            return _customerAccountsExcelExporter.ExportToFile(customerAccountListDtos);
         }


    }
}